import 'package:ref/plugin/helpers/update.dart';

import 'ref.dart';

class ComputeComputeFactory {
  RefCompute instance;
  List<dynamic> refs = [];
  ComputeComputeFactory(this.instance);

  dispose() {
    // 清除依赖
    refs.forEach((ele) {
      ele.dispose(this);
    });
  }
}

late dynamic globalRefComputeInstance = '';
typedef ComputeHandlerCallback = dynamic Function();

class RefCompute<T> extends Ref {
  dynamic _data;
  bool _dirty = true;
  ComputeHandlerCallback _handler;
  late ComputeComputeFactory _computeCollector;

  RefCompute(this._handler) : super(null) {
    _computeCollector = ComputeComputeFactory(this);
  }

  _excute() {
    globalRefComputeInstance = _computeCollector;
    dynamic result = this._handler();
    globalRefComputeInstance = null;
    return result;
  }

  /// 执行事件（请勿调用）
  ///
  /// 请不要调用这个方法
  excute() {
    _dirty = true;
    this.value;
  }

  T get value {
    super.collect();
    if (_dirty) {
      dynamic currentValue = _excute();
      if (currentValue != _data) {
        _data = currentValue;

        /// 数据发生改变，
        Ref.update(() {}, UpdateOptions(refs: [this]));
      }
      _dirty = false;
    }
    return _data;
  }

  @override
  set(Function() modifyier) {
    print('app wrong: RefCompute set value 不能赋值！');
    throw new TypeError();
  }

  @override
  set value(dynamic val) {
    print('app wrong: RefCompute set value 不能赋值！');
    throw new TypeError();
  }

  /// 清除watch缓存
  ///
  /// (请务必widget卸载的时候清除依赖)
  @override
  dispose([dynamic instance]) {
    if (instance == null) {
      _computeCollector.dispose();
    } else {
      super.dispose(instance);
    }
  }
}
